import { Injectable, UseFilters } from '@nestjs/common';
import { CreateMenuDto, UpdateMenuDto } from './dto/menu.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Connection, TreeRepository } from 'typeorm';
import { MenuEntity } from './entities/menu.entity';
import { MenuButtonEntity } from './entities/menuButton.entity';
import { throwHttp } from 'src/utlis';
import { HttpExceptionFilter } from 'src/common/http-exception.filter';
import { IdDto } from 'src/common/dto/dto';
import { isTrue } from 'src/utlis/tools';
import { CreateMenuButtonDto, UpdateMenuButtonDto } from './dto/menuButtom.dto';
import { menuList } from './uilts';

@Injectable()
export class MenuService {
  constructor(
    @InjectRepository(MenuEntity)
    private readonly menuEntityRepository: TreeRepository<MenuEntity>,
    @InjectRepository(MenuButtonEntity)
    private readonly menuButtonEntityRepository: Repository<MenuButtonEntity>,
    private readonly connection: Connection,
  ) { }
  /** 菜单列表 */
  async getMenuTree() {
    try {
      const data = await this.menuEntityRepository.findTrees({
        relations: ['children', 'menuButton'],
      });
      return this.sortTree(data);
    } catch (error) {
      throwHttp(error.message);
    }
  }
  // 递归排序分类树
  private sortTree(categories: MenuEntity[]): MenuEntity[] {
    return categories
      .sort((a, b) => a.sort - b.sort) // 根据 order 字段排序
      .map(menu => {
        if (menu.children) {
          menu.children = this.sortTree(menu.children); // 递归排序子分类
        }
        return menu;
      });
  }

  // 创建菜单
  @UseFilters(new HttpExceptionFilter())
  async createMenu(body: CreateMenuDto, userId: number): Promise<MenuEntity> {
    try {
      const menu = new MenuEntity();
      menu.name = body.name;
      menu.path = body.path;
      menu.route = body.route;
      menu.sort = body.sort;
      menu.type = body.type;
      menu.is_use = body.is_use;
      menu.is_navbar = body.is_navbar;
      menu.description = body.description;
      menu.createById = userId;
      if (isTrue(body.parentId)) {
        const parent = await this.menuEntityRepository.findOne({ where: { id: body.parentId } });
        if (!parent) {
          throwHttp('未找到上级菜单');
          return
        }
        menu.parent = parent;
      }
      return await this.menuEntityRepository.manager.save(menu);
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 更新菜单 */
  @UseFilters(new HttpExceptionFilter())
  async updateMenu(body: UpdateMenuDto,) {
    try {
      const menu = await this.menuEntityRepository.findOne({ where: { id: body.id } });
      if (!menu) {
        throwHttp('未找到菜单');
        return
      }
      if (isTrue(body.parentId)) {
        const parent = await this.menuEntityRepository.findOne({ where: { id: body.parentId } });
        if (!parent) {
          throwHttp('未找到上级菜单');
          return
        }
      }
      const { name, path, route, sort, type, is_use, is_navbar, description } = body
      const { affected } = await this.menuEntityRepository
        .createQueryBuilder()
        .update(MenuEntity)
        .set({ name, path, route, sort, type, is_use, is_navbar, description })
        .where('id = :id', { id: body.id })
        .execute();
      if (affected) {
        return {
          msg: '修改成功',
          data: menu
        };
      }
      throwHttp('修改失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 删除菜单 */
  @UseFilters(new HttpExceptionFilter())
  async deleteMenu({ id }: IdDto) {
    try {
      const data = await this.menuEntityRepository.findOne({
        where: { id },
        cache: true,
      });
      if (!isTrue(data)) {
        throwHttp('菜单不存在');
        return;
      }
      await this.menuEntityRepository.softDelete(id);
      return '删除成功';
    } catch (error) {
      throwHttp(error.message);
    }
  }

  // 创建菜单按钮
  @UseFilters(new HttpExceptionFilter())
  async createMenuButton(body: CreateMenuButtonDto): Promise<MenuButtonEntity> {
    try {
      const menu = new MenuButtonEntity();
      menu.name = body.name;
      menu.key = body.key;
      menu.menuId = body.menuId;
      return await this.menuButtonEntityRepository.manager.save(menu);
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 更新菜单按钮 */
  @UseFilters(new HttpExceptionFilter())
  async updateMenuButton(body: UpdateMenuButtonDto,) {
    try {
      const menuButton = await this.menuButtonEntityRepository.findOne({ where: { id: body.id } });
      if (!menuButton) {
        throwHttp('未找到菜单按钮');
        return
      }
      const { key, name, menuId } = body
      const { affected } = await this.menuButtonEntityRepository
        .createQueryBuilder()
        .update(MenuButtonEntity)
        .set({ key, name, menuId })
        .where('id = :id', { id: body.id })
        .execute();
      if (affected) {
        return {
          msg: '修改成功',
          data: menuButton
        };
      }
      throwHttp('修改失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 删除菜单 */
  @UseFilters(new HttpExceptionFilter())
  async deleteMenuButton({ id }: IdDto) {
    try {
      const data = await this.menuButtonEntityRepository.findOne({
        where: { id },
        cache: true,
      });
      if (!isTrue(data)) {
        throwHttp('菜单按钮不存在');
        return;
      }
      await this.menuButtonEntityRepository.softDelete(id);
      return '删除成功';
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 
 * 初始化菜单（包含递归处理） 
 * @param userId 创建者用户ID 
 */
  @UseFilters(new HttpExceptionFilter())
  async addMenuIfNotExists(userId: number) {
    try {
      // 遍历并处理每个菜单项（使用递归）
      for (const menu of menuList) {
        await this.createMenuRecursive(menu, userId);
      }
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /**
   * 递归创建菜单及其子菜单和按钮
   * @param menu 菜单项
   * @param userId 创建者用户ID
   * @param parentId 父菜单ID（可选）
   */
  private async createMenuRecursive(menu: any, userId: number, parentId?: number) {
    try {
      // 创建当前菜单
      const data = await this.createMenu(
        {
          ...menu,
          parentId,
        } as any,
        userId,
      );

      // 处理菜单按钮
      if (menu.menuButton && menu.menuButton.length > 0) {
        for (const button of menu.menuButton) {
          await this.createMenuButton({
            ...button,
            menuId: data.id,
          });
        }
      }

      // 递归处理子菜单
      if (menu.children && menu.children.length > 0) {
        for (const child of menu.children) {
          await this.createMenuRecursive(child, userId, data.id);
        }
      }
    } catch (error) {
      throwHttp(`菜单初始化失败: ${menu.name}, 错误信息: ${error.message}`);
    }
  }
}
